﻿using System;
using System.Collections.Generic;
using System.IO;
using Ionic.Zip;
using Ionic.Zlib;

namespace Up2DateFramework
{
    /// <summary>
    /// Compressor Klasse, die Schnittstelle zu den Kompressions Bibliotheken (DotNetZip, SevenZipSharp)
    /// </summary>
    public class Compressor
    {
        #region DotNetZip Library -------------------------------------------------------------------------------------
       
        #region Generierung von Zip Dateien mit List<> und HashSets<>

        /// <summary>
        /// Generiert ein Zip Archiv aus jeder gefundenen Datei des angegebenen Ordners
        /// </summary>
        /// <param name="outputPath">Der Pfad wo die Zip Archive gespeichert werden sollen</param>
        /// <param name="filePath">Die Datei die gepackt werden soll</param>
        /// <returns>Gibt einen Bool Wert zurück. True für erfolgreich und false für gescheitert</returns>
        public static bool GenerateOneZipArchiveEachFile(string outputPath, string filePath)
        {
            try
            {
                using (ZipFile zip = new ZipFile())
                {
                    FileInfo fi = new FileInfo(filePath);
                    zip.AddFile(fi.FullName);
                    zip.Save(Path.Combine(outputPath,fi.Name.Split('.')[0]+".zip"));
                    return true;
                }
            }
            catch
            {
                return false;
            }
            
        }

        /// <summary>
        /// Generiert ein Zip Archiv aus jeder gefundenen Datei des angegebenen Ordners
        /// </summary>
        /// <param name="filePath">Die Datei die gepackt werden soll</param>
        /// <returns>Gibt einen Bool Wert zurück. True für erfolgreich und false für gescheitert</returns>
        public static bool GenerateOneZipArchiveEachFile(string filePath)
        {
            try
            {
                using (ZipFile zip = new ZipFile())
                {
                    FileInfo fi = new FileInfo(filePath);
                    zip.AddFile(fi.FullName);
                    zip.Save(fi.Name.Split('.')[0] + ".zip");
                    return true;
                }
            }
            catch
            {
                return false;
            }

        }

        /// <summary>
        /// Generiert ein Zip Archiv aus den gefundenen Datei des angegebenen Ordners
        /// </summary>
        /// <param name="outputPath">Der Pfad wo die Zip Archive gespeichert werden sollen</param>
        /// <param name="archivename">Der Archivename</param>
        /// <param name="password">Das Password für das Archiv</param>
        /// <param name="directoryPathInArchive">Der Virtuelle Pfad innerhalb des Archives</param>
        /// <param name="filePaths">Die Dateien die gepackt werden soll (List)</param>
        /// <returns>Gibt einen Bool Wert zurück. True für erfolgreich und false für gescheitert</returns>
        public static bool GenerateZip(string outputPath, string archivename, string password,
                                       string directoryPathInArchive, List<string> filePaths)
        {
            try
            {
                using (ZipFile zip = new ZipFile())
                {
                    zip.Password = password;
                    foreach (string file in filePaths)
                        zip.AddFile(file,directoryPathInArchive);
                    zip.Save(Path.Combine(outputPath,archivename));
                    return true;
                }
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// Generiert ein Zip Archiv aus den gefundenen Datei des angegebenen Ordners
        /// </summary>
        /// <param name="outputPath">Der Pfad wo die Zip Archive gespeichert werden sollen</param>
        /// <param name="archivename">Der Archivename</param>
        /// <param name="password">Das Password für das Archiv</param>
        /// <param name="comment">Ein Kommentar für das Archiv</param>
        /// <param name="directoryPathInArchive">Der Virtuelle Pfad innerhalb des Archives</param>
        /// <param name="filePaths">Die Dateien die gepackt werden soll (List)</param>
        /// <returns>Gibt einen Bool Wert zurück. True für erfolgreich und false für gescheitert</returns>
        public static bool GenerateZip(string outputPath, string archivename, string password, string comment,
                                       string directoryPathInArchive, List<string> filePaths)
        {
            try
            {
                using (ZipFile zip = new ZipFile())
                {
                    zip.Password = password;
                    foreach (string file in filePaths)
                        zip.AddFile(file, directoryPathInArchive);
                    zip.Comment = comment;
                    zip.Save(Path.Combine(outputPath, archivename));
                    return true;
                }
            }
            catch
            {
                return false;
            }
        }
        /// <summary>
        /// Generiert ein Zip Archiv aus den gefundenen Datei des angegebenen Ordners
        /// </summary>
        /// <param name="outputPath">Der Pfad wo die Zip Archive gespeichert werden sollen</param>
        /// <param name="archivename">Der Archivename</param>
        /// <param name="directoryPathInArchive">Der Virtuelle Pfad innerhalb des Archives</param>
        /// <param name="filePaths">Die Dateien die gepackt werden soll (List)</param>
        /// <returns>Gibt einen Bool Wert zurück. True für erfolgreich und false für gescheitert</returns>
        public static bool GenerateZip(string outputPath, string archivename, 
                                       string directoryPathInArchive, List<string> filePaths)
        {
            try
            {
                using (ZipFile zip = new ZipFile())
                {
                    foreach (string file in filePaths)
                        zip.AddFile(file, directoryPathInArchive);
                    zip.Save(Path.Combine(outputPath, archivename));
                    return true;
                }
            }
            catch
            {
                return false;
            }
        }
        /// <summary>
        /// Generiert ein Zip Archiv aus den gefundenen Datei des angegebenen Ordners
        /// </summary>
        /// <param name="outputPath">Der Pfad wo die Zip Archive gespeichert werden sollen</param>
        /// <param name="archivename">Der Archivename</param>
        /// <param name="filePaths">Die Dateien die gepackt werden soll (List)</param>
        /// <returns>Gibt einen Bool Wert zurück. True für erfolgreich und false für gescheitert</returns>
        public static bool GenerateZip(string outputPath, string archivename,List<string> filePaths)
        {
            try
            {
                using (ZipFile zip = new ZipFile())
                {
                    foreach (string file in filePaths)
                        zip.AddFile(file);
                    zip.Save(Path.Combine(outputPath, archivename));
                    return true;
                }
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// Generiert ein Zip Archiv aus den gefundenen Datei des angegebenen Ordners
        /// </summary>
        /// <param name="outputPath">Der Pfad wo die Zip Archive gespeichert werden sollen</param>
        /// <param name="archivename">Der Archivename</param>
        /// <param name="password">Das Password für das Archiv</param>
        /// <param name="directoryPathInArchive">Der Virtuelle Pfad innerhalb des Archives</param>
        /// <param name="filePaths">Die Dateien die gepackt werden soll (HashSet)</param>
        /// <returns>Gibt einen Bool Wert zurück. True für erfolgreich und false für gescheitert</returns>
        public static bool GenerateZip(string outputPath, string archivename, string password,
                                       string directoryPathInArchive, HashSet<string> filePaths)
        {
            try
            {
                using (ZipFile zip = new ZipFile())
                {
                    zip.Password = password;
                    foreach (string file in filePaths)
                        zip.AddFile(file, directoryPathInArchive);
                    zip.Save(Path.Combine(outputPath, archivename));
                    return true;
                }
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// Generiert ein Zip Archiv aus den gefundenen Datei des angegebenen Ordners
        /// </summary>
        /// <param name="outputPath">Der Pfad wo die Zip Archive gespeichert werden sollen</param>
        /// <param name="archivename">Der Archivename</param>
        /// <param name="password">Das Password für das Archiv</param>
        /// <param name="comment">Ein Kommentar für das Archiv</param>
        /// <param name="directoryPathInArchive">Der Virtuelle Pfad innerhalb des Archives</param>
        /// <param name="filePaths">Die Dateien die gepackt werden soll (HashSet)</param>
        /// <returns>Gibt einen Bool Wert zurück. True für erfolgreich und false für gescheitert</returns>
        public static bool GenerateZip(string outputPath, string archivename, string password, string comment,
                                       string directoryPathInArchive, HashSet<string> filePaths)
        {
            try
            {
                using (ZipFile zip = new ZipFile())
                {
                    zip.Password = password;
                    foreach (string file in filePaths)
                        zip.AddFile(file, directoryPathInArchive);
                    zip.Comment = comment;
                    zip.Save(Path.Combine(outputPath, archivename));
                    return true;
                }
            }
            catch
            {
                return false;
            }
        }
        /// <summary>
        /// Generiert ein Zip Archiv aus den gefundenen Datei des angegebenen Ordners
        /// </summary>
        /// <param name="outputPath">Der Pfad wo die Zip Archive gespeichert werden sollen</param>
        /// <param name="archivename">Der Archivename</param>
        /// <param name="directoryPathInArchive">Der Virtuelle Pfad innerhalb des Archives</param>
        /// <param name="filePaths">Die Dateien die gepackt werden soll (List)</param>
        /// <returns>Gibt einen Bool Wert zurück. True für erfolgreich und false für gescheitert</returns>
        public static bool GenerateZip(string outputPath, string archivename,
                                       string directoryPathInArchive, HashSet<string> filePaths)
        {
            try
            {
                using (ZipFile zip = new ZipFile())
                {
                    foreach (string file in filePaths)
                        zip.AddFile(file, directoryPathInArchive);
                    zip.Save(Path.Combine(outputPath, archivename));
                    return true;
                }
            }
            catch
            {
                return false;
            }
        }
        /// <summary>
        /// Generiert ein Zip Archiv aus den gefundenen Datei des angegebenen Ordners
        /// </summary>
        /// <param name="outputPath">Der Pfad wo die Zip Archive gespeichert werden sollen</param>
        /// <param name="archivename">Der Archivename</param>
        /// <param name="filePaths">Die Dateien die gepackt werden soll (List)</param>
        /// <returns>Gibt einen Bool Wert zurück. True für erfolgreich und false für gescheitert</returns>
        public static bool GenerateZip(string outputPath, string archivename, HashSet<string> filePaths)
        {
            try
            {
                using (ZipFile zip = new ZipFile())
                {
                    foreach (string file in filePaths)
                        zip.AddFile(file);
                    zip.Save(Path.Combine(outputPath, archivename));
                    return true;
                }
            }
            catch
            {
                return false;
            }
        }


        public static void ListAllEntries(string archivePath)
        {
            using (ZipFile zip = ZipFile.Read(archivePath))
            {
                foreach (ZipEntry e in zip)
                {
                    
                        Console.WriteLine("Zipfile: {0}", zip.Name);
                        if (!string.IsNullOrEmpty(zip.Comment))
                            Console.WriteLine("Comment: {0}", zip.Comment);
                        System.Console.WriteLine("\n{1,-22} {2,8}  {3,5}   {4,8}  {5,3} {0}",
                                                 "Filename", "Modified", "Size", "Ratio", "Packed", "pw?");
                        System.Console.WriteLine(new System.String('-', 72));

                    
                    Console.WriteLine("{1,-22} {2,8} {3,5:F0}%   {4,8}  {5,3} {0}",
                                             e.FileName,
                                             e.LastModified.ToString("yyyy-MM-dd HH:mm:ss"),
                                             e.UncompressedSize,
                                             e.CompressionRatio,
                                             e.CompressedSize,
                                             (e.UsesEncryption) ? "Y" : "N");

                }
            }

        }
        
        #endregion

        
        #endregion ----------------------------------------------------------------------------------------------------

        #region SevenZipSharp Library ---------------------------------------------------------------------------------

        #endregion ----------------------------------------------------------------------------------------------------
    }
}
